/*
 * Copyright 2021-2022 the original author(https://github.com/wj596)
 * 
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */
package org.jsets.fastboot.security.authc;

import org.jsets.fastboot.security.SecurityUtils;
import org.jsets.fastboot.security.config.Constants;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 认证器
 * 
 * @author wj596
 *
 */
@Slf4j
public class LoginHandlerImpl implements ILoginHandler {

	@Override
	public UserDetails doLogin(AuthcRequest authcRequest) throws AuthenticationException {
		UserDetails userDetails = SecurityUtils.getUserInfoProvider().loadUserByUsername(authcRequest.getAuthType(),authcRequest.getUsername());
		if (null == userDetails) {
			SecurityUtils.getListenerManager().onLoginFailure(authcRequest, "用户不存在");
			throw new UsernameNotFoundException(SecurityUtils.getProperties().getUsernameOrPasswdErrorTips());
		}

		if (!userDetails.isAccountNonLocked()) {
			SecurityUtils.getListenerManager().onLoginFailure(authcRequest, "用户账号被锁定");
			throw new UsernameNotFoundException(SecurityUtils.getProperties().getUsernameLockedTips());
		}

		if (!SecurityUtils.getPasswordEncoder().matches(authcRequest.getPassword(), userDetails.getPassword())) {
			this.onPasswordError(authcRequest);
		}
		SecurityUtils.getPasswdRetryWatcher().cleanup(authcRequest.getUsername());

		return userDetails;
	}

	protected void onPasswordError(AuthcRequest authcRequest) {
		int count = SecurityUtils.getPasswdRetryWatcher().increase(authcRequest.getUsername());
		String msg = SecurityUtils.getProperties().getUsernameOrPasswdErrorTips();
		if (count > 0) {
			msg = SecurityUtils.getPasswdRetryWatcher().onPasswdRetry(authcRequest.getUsername(), count);
		}
		SecurityUtils.getListenerManager().onLoginFailure(authcRequest, "密码不正确");
		throw new BadCredentialsException(msg);
	}
	
	@Override
	public String getSupportAuthcType() {
		return Constants.DEFAULT_AUTHC_TYPE;
	}

}